package xxl.signals.util 
{
	import flash.errors.IllegalOperationError;
	import flash.utils.Dictionary;
	import xxl.signals.api.ISlot;
	/**
	 * ...
	 * @author XXL
	 */
	public class SignalUtil 
	{
		[Inline]
		public static function RegistrationPossible(slotCache:Dictionary, listener:Function, once:Boolean):Boolean
		{
			const existingSlot:ISlot = slotCache[listener];
			if (!existingSlot)
			{
				return true;
			}
			if (existingSlot.once != once)
			{
				throw new IllegalOperationError("不能重复注册不同once的相同listener");
			}
			return false;
		}
		
		[Inline]
		public static function VerifyDispatch(valueClasses:Array, valueObjects:Array):void
		{
			const numValueClasses:int = valueClasses.length;
			const numValueObjects:int = valueObjects.length;
			if (numValueObjects < numValueClasses)
			{
				throw new ArgumentError("至少需要" + numValueClasses + "个参数，实际只传了" + numValueObjects + "个参数")
			}
			for (var i:int = 0; i < numValueClasses; i++)
			{
				if (valueObjects[i] is valueClasses[i] || valueObjects[i] === null)
				{
					continue;
				}
				throw new ArgumentError(valueObjects[i] + "不是" + valueClasses[i]);
			}
		}
		
		[Inline]
		public static function VerifyValueClasses(valueClasses:Array):void
		{
			const len:int = valueClasses.length;
			for (var i:int = 0; i < len; i++) 
			{
				if (!(valueClasses[i] is Class))
				{
					throw new ArgumentError("参数" + i + "不是Class");
				}
			}
		}
		
		[Inline]
		public static function RemoveSlot(slots:Array, listener:Function):ISlot
		{
			for (var i:int = slots.length; i--; )
			{
				var slot:ISlot = slots[i];
				if (slot.listener == listener)
				{
					slots.splice(i, 1);
					return slot;
				}
			}
			return null;
		}
		
		[Inline]
		public static function RemoveSlotFromVector(slots:Vector.<ISlot>, listener:Function):ISlot
		{
			for (var i:int = slots.length; i--; )
			{
				var slot:ISlot = slots[i];
				if (slot.listener == listener)
				{
					slots.splice(i, 1);
					return slot;
				}
			}
			return null;
		}
		
		[Inline]
		public static function Apply(target:Object, fun:Function, params:Array):void
		{
			if (fun)
			{
				const len:int = params.length;
				if (len == 0)
				{
					fun();
				}
				else if (len == 1)
				{
					fun(params[0]);
				}
				else if (len == 2)
				{
					fun(params[0], params[1]);
				}
				else if (len == 3)
				{
					fun(params[0], params[1], params[2]);
				}
				else if (len == 4)
				{
					fun(params[0], params[1], params[2], params[3]);
				}
				else if (len == 5)
				{
					fun(params[0], params[1], params[2], params[3], params[4]);
				}
				else
				{
					fun.apply(target, params);
				}
			}
		}
		
	}

}